package org.arclib.x.sprite;

import org.arclib.Window;
import org.arclib.draw.Color;
import org.arclib.math.Common;
import org.arclib.math.Point;
import org.arclib.math.Size;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;

public class Entity
{
	// / initialize OpenGL parameters required to draw
	public void initGL()
	{
		GL11.glEnable(GL11.GL_TEXTURE_2D);
		GL11.glEnable(GL11.GL_BLEND);
		GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
	}

	/*******************************************************************************
	 * Test if mouse is over entity
	 *******************************************************************************/
	public boolean mouseOver()
	{
		return xyCol(new Point(Mouse.getX(), Mouse.getY()));
	}

	/*******************************************************************************
	 * Test if given coordinate is over entity, simple box collision
	 *******************************************************************************/
	public boolean xyCol(Point p)
	{
		double max_size = size.maxComponent();

		if (p.x > pos.x && p.x < pos.x + max_size && p.y > pos.y
				&& p.y < pos.y + max_size)
		{
			return true;
		}

		return false;
	}

	/*******************************************************************************
	 * Left mouse clicks on entity
	 *******************************************************************************/
	public boolean mouseHit()
	{
		if (mouseOver() && Keyboard.isKeyDown(Keyboard.KEY_LEFT))
			return true;

		return false;
	}

	// / returns true if entity is on the screen
	public boolean onScreen()
	{
		double max_size = size.maxComponent();

		if (pos.x >= -max_size && pos.x <= Window.getWidth() + max_size
				&& pos.y >= -max_size && pos.y <= Window.getHeight() + max_size)
			return true;

		return false;
	}

	// / set position
	public void setPosition(double x, double y)
	{
		pos.set(x, y);
	}

	// / set position based on point
	public void setPosition(Point p)
	{
		pos = p;
	}

	// / set size
	public void setSize(double width, double height)
	{
		size.set(width, height);
	}

	// / just set X value
	public void setX(double x)
	{
		pos.x = x;
	}

	// / just set Y value
	public void setY(double y)
	{
		pos.y = y;
	}

	// / add value to X
	public void addX(double x)
	{
		pos.x += x;
	}

	// / add value to Y
	public void addY(double y)
	{
		pos.y += y;
	}

	// / change color of entity
	public void setColor(Color aC)
	{
		color = aC;
	}

	// / return x position
	public double getX()
	{
		return pos.x;
	}

	// / return y position
	public double getY()
	{
		return pos.y;
	}

	// / return entity width
	public double getWidth()
	{
		return size.w;
	}

	// / return entity height
	public double getHeight()
	{
		return size.h;
	}

	// / return center X position of entity
	public double getCenterX()
	{
		return pos.x + (size.w / 2);
	}

	// / return center Y position of entity
	public double getCenterY()
	{
		return pos.y + (size.h / 2);
	}

	// / return half of entity's width
	public double getHalfWidth()
	{
		return getWidth() / 2;
	}

	// / return half of entity's height
	public double getHalfHeight()
	{
		return getHeight() / 2;
	}

	// / return position as a point
	public Point getPosition()
	{
		return pos;
	}

	// / return size as a point
	public Size getSize()
	{
		return size;
	}

	// / returns true if entity is within proximity of x and y value
	public boolean inRange(double argX, double argY, double argProx)
	{
		// if x and y are within proximity distance
		if (Common.withinRange(getX(), argX, argProx)
				&& Common.withinRange(getY(), argY, argProx))
		{
			return true; // we are within range
		}

		return false;
	}

	// / set width
	public void setWidth(double argW)
	{
		size.w = argW;
	}

	// / set height
	public void setHeight(double argH)
	{
		size.h = argH;
	}

	/***
	 * return the distance between two entities
	 */
	public double distance(Entity a)
	{
		return Common.distance(getCenterX(), getCenterY(), a.getCenterX(), a
				.getCenterY());
	}

	/***
	 * return the distance between entity and two points
	 */
	public double distance(double x2, double y2)
	{
		return Common.distance(getCenterX(), getCenterY(), x2, y2);
	}

	public final Color getColor()
	{
		return color;
	}

	// Everything in the game world needs a position, size, and color
	private Point pos = Point.Zero;
	private Size size = Size.Zero;

	private Color color = Color.White;
}
